/*
 * @(#)SimpleMoneyFormat.java        1.0 2013-8-7
 *
 * Copyright (c) 2007-2013 ChongQing Zhengda Software(Group)Co.,Ltd.
 * C-31-5 New North Zone.ChongQing.China
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of 
 *  ChongQing Zhengda Software(Group)Co.,Ltd. ("Confidential Information").  
 * You shall not disclose such Confidential Information and shall use 
 * it only in accordance with the terms of the license agreement you 
 * entered into with ChongQing Zhengda Software(Group).
 */

package org.goyo.common.utils;

/**
 * @(#)SimpleMoneyFormat.java
 *
 *金额转换，阿拉伯数字的金额转换为中国传统的形式输出
 * @lpxuan
 * @version 1.00 2008/7/31
 */

import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.lang.StringBuffer;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;

public class SimpleMoneyFormat {

    public static final String EMPTY="";
    public static final String NEGATIVE ="负";
    public static final String ZERO="零";
    public static final String ONE="壹";
    public static final String TWO="贰";
    public static final String THREE="叁";
    public static final String FOUR="肆";
    public static final String FIVE="伍";
    public static final String SIX="陆";
    public static final String SEVEN="柒";
    public static final String EIGHT="捌";
    public static final String NINE="玖";
    public static final String TEN="拾";
    public static final String HUNDRED="佰";
    public static final String THOUSAND="仟";
    public static final String TEN_THOUSAND="万";
    public static final String HUNDRED_MILLION="亿";
    public static final String YUAN="元";
    public static final String JIAO="角";
    public static final String FEN="分";
    public static final String DOT=".";
    public static final String NEGATIVESIGN ="-";
   
    private static SimpleMoneyFormat formatter=null;
    private HashMap chineseNumberMap=new HashMap();
    private HashMap chineseMoenyPattern=new HashMap();
    private NumberFormat numberFormat=NumberFormat.getInstance();
    //private HashMap chineseSignMap = new HashMap();
   
    //私有构造函数
    private SimpleMoneyFormat() {
     numberFormat.setMaximumFractionDigits(4);
     numberFormat.setMinimumFractionDigits(2);
     numberFormat.setGroupingUsed(false);
     
     chineseNumberMap.put("-",NEGATIVE);
     chineseNumberMap.put("0",ZERO);
     chineseNumberMap.put("1",ONE);
     chineseNumberMap.put("2",TWO);
     chineseNumberMap.put("3",THREE);
     chineseNumberMap.put("4",FOUR);
     chineseNumberMap.put("5",FIVE);
     chineseNumberMap.put("6",SIX);
     chineseNumberMap.put("7",SEVEN);
     chineseNumberMap.put("8",EIGHT);
     chineseNumberMap.put("9",NINE);
     chineseNumberMap.put(DOT,DOT);
     
     chineseMoenyPattern.put("1",TEN);
     chineseMoenyPattern.put("2",HUNDRED);
     chineseMoenyPattern.put("3",THOUSAND);
     chineseMoenyPattern.put("4",TEN_THOUSAND);
     chineseMoenyPattern.put("5",TEN);
     chineseMoenyPattern.put("6",HUNDRED);
     chineseMoenyPattern.put("7",THOUSAND);
     chineseMoenyPattern.put("8",HUNDRED_MILLION);
    }
   
    //单例模式
    public static SimpleMoneyFormat getInstance(){
     if(formatter==null)
      formatter=new SimpleMoneyFormat();
     return formatter;
    }
   
    public String format(String moneyStr){
     checkPrecision(moneyStr);
     String result;
     result=convertToChineseNumber(moneyStr);
     result=addUnitsToChineseMoenyString(result);
     return result;
    }
   
    public String format(double moneyDouble){
     return format(numberFormat.format(moneyDouble));
    }
   
    public String format(int moneyInt){
     return format(numberFormat.format(moneyInt));
    }
   
    public String format(long moneyLong){
     return format(numberFormat.format(moneyLong));
    }
   
    public String format(Number moneyNum){
     return format(numberFormat.format(moneyNum));
    }
   
    private String convertToChineseNumber(String moneyStr){
     String result;
     StringBuffer cMoneyStringBuffer =new StringBuffer();
     for(int i=0;i<moneyStr.length();i++){
      cMoneyStringBuffer.append(chineseNumberMap.
       get(moneyStr.substring(i,i+1)));
     }
     
     int indexOfDot=cMoneyStringBuffer.indexOf(DOT);
     int moneyPatternCursor=1;
     for(int i=indexOfDot-1;i>0;i--){
    	 char c =cMoneyStringBuffer.charAt(i-1);
    	 if((c+"").equals(NEGATIVE)){
    		 continue;
    	 }
      cMoneyStringBuffer.insert(i,
          chineseMoenyPattern.get(EMPTY+moneyPatternCursor));
      moneyPatternCursor=moneyPatternCursor==
       8?1:moneyPatternCursor+1;
     }
     
     String fractionPart=cMoneyStringBuffer.substring(
      cMoneyStringBuffer.indexOf("."));
        cMoneyStringBuffer.delete(
         cMoneyStringBuffer.indexOf("."),
             cMoneyStringBuffer.length());
        while(cMoneyStringBuffer.indexOf("零拾")!=-1){
         cMoneyStringBuffer.replace(
          cMoneyStringBuffer.indexOf("零拾"),
              cMoneyStringBuffer.indexOf("零拾")+2,ZERO);
        }
        while(cMoneyStringBuffer.indexOf("零佰")!=-1){
         cMoneyStringBuffer.replace(
          cMoneyStringBuffer.indexOf("零佰"),
                 cMoneyStringBuffer.indexOf("零佰")+2,ZERO);
        }
        while(cMoneyStringBuffer.indexOf("零仟")!=-1){
         cMoneyStringBuffer.replace(
          cMoneyStringBuffer.indexOf("零仟"),
                 cMoneyStringBuffer.indexOf("零仟")+2,ZERO);
        }
        while(cMoneyStringBuffer.indexOf("零万")!=-1){
         cMoneyStringBuffer.replace(
          cMoneyStringBuffer.indexOf("零万"),
             cMoneyStringBuffer.indexOf("零万")+2,TEN_THOUSAND);
        }
        while(cMoneyStringBuffer.indexOf("零亿")!=-1){
         cMoneyStringBuffer.replace(
          cMoneyStringBuffer.indexOf("零亿"),
             cMoneyStringBuffer.indexOf("零亿")+2,HUNDRED_MILLION);
        }
        while(cMoneyStringBuffer.indexOf("零零")!=-1){
         cMoneyStringBuffer.replace(
          cMoneyStringBuffer.indexOf("零零"),
             cMoneyStringBuffer.indexOf("零零")+2,ZERO);
        }
        if(cMoneyStringBuffer.lastIndexOf(ZERO)
         ==cMoneyStringBuffer.length()-1){
         cMoneyStringBuffer.delete(
          cMoneyStringBuffer.length()-1,
          cMoneyStringBuffer.length());
        }
        cMoneyStringBuffer.append(fractionPart);
        result=cMoneyStringBuffer.toString();
        return result;
    }
   
    private String addUnitsToChineseMoenyString(String moneyStr){
     String result;
     StringBuffer cMoneyStringBuffer=new StringBuffer(moneyStr);
     
     int indexOfDot=cMoneyStringBuffer.indexOf(DOT);
     cMoneyStringBuffer.replace(indexOfDot,indexOfDot+1,YUAN);
     cMoneyStringBuffer.insert(cMoneyStringBuffer.length()-1,JIAO);
     cMoneyStringBuffer.insert(cMoneyStringBuffer.length(),FEN);
     
      //拾佰仟万亿等都是汉字里面才有的单位，加上它们
     if(cMoneyStringBuffer.indexOf("零角零分")!=-1)//去掉零头，加整
      cMoneyStringBuffer.replace(cMoneyStringBuffer.indexOf("零角零分"),
       cMoneyStringBuffer.length(),"整");
     else if(cMoneyStringBuffer.indexOf("零分")!=-1)//去掉零分，加整
         cMoneyStringBuffer.replace(cMoneyStringBuffer.indexOf("零分"),
             cMoneyStringBuffer.length(),"整");
     else if(cMoneyStringBuffer.indexOf("零角")!=-1)
      cMoneyStringBuffer.delete(cMoneyStringBuffer.indexOf("零角"),
           cMoneyStringBuffer.indexOf("零角")+2);
         result=cMoneyStringBuffer.toString();
         return result;
    }
   
    //检查精度的合法性
    private void checkPrecision(String moneyStr){
     int fractionDigits=moneyStr.length()-moneyStr.indexOf(DOT)-1;
     if(fractionDigits>2)//精度不能比分低
      throw new RuntimeException("金额"+moneyStr+"的小数位数多余两位.");
    }
    
    /**
     * 以下处理各种字符格式
     */
    /**
     * 返回当前缺省语言环境的缺省数值格式。
     */
    public static final String GETINSTANCE ="getInstance";
    
    /**
     * 返回当前缺省语言环境的缺省数值格式。
     */
    public static final String GETINTEGERINSTANCE ="getIntegerInstance";
    
    /**
     * 返回当前缺省语言环境的通用数值格式。
     */
    public static final String GETNUMBERINSTANCE ="getNumberInstance";
    
    /**
     * 返回当前缺省语言环境的百分比格式。
     */
    public static final String GETPERCENTINSTANCE ="getPercentInstance";
    
    /**
     * 返回当前缺省语言环境的通用格式
     */
    public static final String GETCURRENCYINSTANCE ="getCurrencyInstance";
    public static String defaultNumberFormat(double value,String methodType) throws Exception {
    	NumberFormat ff = (NumberFormat) (NumberFormat.class.getMethod(methodType, new Class[] {})).invoke(NumberFormat.class, new Object[] {});
    	return ff.format(value);
     }
    
    
//     public static void customNumberFormat() {
//        double x = 1000.0 / 3;
//        System.out.println("default output is " + x);
//        patternPrint("###,###.##", x);
//        patternPrint("####.##", x);
//        patternPrint("####.00", x);
//        patternPrint("####.0#", x);
//        patternPrint("00000.##", x);
//        patternPrint("$###,###.##", x);
//         patternPrint("0.###E0", x);
//        patternPrint("00.##%", x);
//  
//        double y = 23.0012;
//        System.out.println("default output is " + y);
//        patternPrint("###,###.##", y);
//        patternPrint("####.##", y);
//        patternPrint("####.00", y);
//        patternPrint("####.0#", y);
//        patternPrint("00000.##", y);
//        patternPrint("$###,###.##", y);
//        patternPrint("0.###E0", y);
//        patternPrint("00.##%", y);
//     }
    
     /**
      * 返回当前缺省语言环境的通用数值格式。
      * @param pattern
      * @param x
      */
     public static void patternPrint(String pattern, double x) {
        DecimalFormat df = new DecimalFormat(pattern);
        System.out.println("output for pattern " + pattern + " is " + df.format(x));
     }
    
     public static void defaultDateFormat(){
        Date date = new Date();
       
        System.out.println("simple date " + date.toLocaleString());
       
        DateFormat df = DateFormat.getDateTimeInstance();
        System.out.println(df.format(date));
       
        DateFormat dfLong = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
        System.out.println(dfLong.format(date));
       
        DateFormat dfMedium = DateFormat.getDateTimeInstance(DateFormat.MEDIUM,
            DateFormat.MEDIUM);
        System.out.println(dfMedium.format(date));
  
        DateFormat dfShort = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
        System.out.println(dfShort.format(date));
     }
    
     public static void customDateFormat() {
        Date date = new Date();
        patternPrint("yyyy.MM.dd HH:mm:ss z", date);  //两个MM, dd会导致补零
        patternPrint("yy年M月d日 HH时mm分", date);  //两个yy就显示为两位年份
        patternPrint("EEE, MMM d, ''yy", date);
        patternPrint("h:mm a", date);
        patternPrint("hh 'o''clock' a, zzzz", date);
        patternPrint("yyyyy.MMMMM.dd GGG hh:mm aaa", date);
        patternPrint("EEE, d MMM yyyy HH:mm:ss Z", date);
        patternPrint("yyMMddHHmmssZ", date);
     }
    
     /**
      * 格式化时间
      * @param pattern
      * @param date
      */
     public static void patternPrint(String pattern, Date date){
        SimpleDateFormat df = new SimpleDateFormat(pattern);
        System.out.println(df.format(date));
     }
   
     /**
      * double转换为String
      * @param sn
      * @return
      */
     public static String convertScienceNum(double sn){
    	    NumberFormat numberFormat = NumberFormat.getInstance();
    	    String str = numberFormat.format(sn);
    	    String[] strArray = str.split(",");
    	   StringBuffer buffer = new StringBuffer();
    	   for(int i=0;i<strArray.length;i++){
    	    buffer.append(strArray[i]);
    	   }
    	   return buffer.toString();
     }
     
    public static void main(String[] args){
    	System.out.println(convertScienceNum(334343.345559999999999));
    	try {
			System.out.println(defaultNumberFormat(314324324.1535555555553,GETCURRENCYINSTANCE));
		} catch (Exception e) {
			e.printStackTrace();
		}
    	System.out.println(Double.MAX_VALUE); 
    	System.out.println(Double.MIN_VALUE);
    	
    	double sss = Double.parseDouble("22");
    	double ssss = Double.parseDouble("2078.18");
    	System.out.println(sss);
    	System.out.println(ssss);
    	System.out.println(SimpleMoneyFormat.convertScienceNum(ssss-sss));
    	BigDecimal b1 = new BigDecimal("3.0");//必须用字符串
    	BigDecimal b2 = new BigDecimal("2.9");
    	BigDecimal b = b1.subtract(b2);//会输出0.1
    	System.out.println(b+"---");
    	 double d=1.10+1.30+1.11;
         System.out.println(d);
         BigDecimal bd1=new BigDecimal("-1.5");
         BigDecimal bd2=new BigDecimal("1.30");
         BigDecimal bd3=new BigDecimal("1.11");
         System.out.println(bd1.add(bd2).add(bd3).toString());
         
         BigDecimal i=new BigDecimal(13); 
         BigDecimal x=new BigDecimal(0.85);
         System.out.println(i.add(x));
        /* System.out.println();
         * 
        
        // customNumberFormat();
         System.out.println();
        
         defaultDateFormat();
         System.out.println();
   
         customDateFormat();
         System.out.println();*/
         double dbl=10000.0/3;
         NumberFormat formatter=NumberFormat.getCurrencyInstance();
         String s=formatter.format(314.1544);
         System.out.println(s);
     //System.out.println(getInstance().format(new Double(22.33)));
    }
}

